
using System;
using System.Collections.Generic;
using LibSars;
using ajma.Utils;
using System.Threading;
using System.Windows.Forms;
using SarsClient.GUI;

namespace SarsClient
{
	
	///<summary>Main controller class for GUI client.</summary> 
	public class MainController {
		
		#region Private class members.
		
		/// <summary>Old SARS main form.</summary>
		MainForm form;
        
		/// <summary>Connection Manager.</summary>
		ConnectionManager cmgr;
		/// <summary>Control Center form.</summary>
        ControlCenter controlCenter;
        /// <summary>PeerAcceptor object of this client.</summary>
		PeerAcceptor pa;
		 /// <summary>Thread for connection Manager.</summary>
		 //TODO: replace?
		Thread cmgrThread;

        MessageSender sender1;

		// Event handler for message display
		public DelDisplayMessage OnDisplayMessage;
		
		#endregion
		
		
		
		#region Private methods.
		
		/// <summary>Register own actions on form.</summary>
		void SubscribeOnForm(MainForm _form){
			_form.OnSendMessage += new DelSendMessage(this.SendMessageHandler);
			_form.OnExitApp += new DelExitApp(this.Stop);
		}
		
		void SubscribeOnControlCenter(ControlCenter _controlCenter){
			// Bad: binds action of ConnectionManager _directly_ to form.
			_controlCenter.OnConnectToIp += new DelConnectToIp(cmgr.ConnectTo);
		}
		
		#endregion
		
		#region Public methods.
		
		/// <summary>
		/// Default constructor.
		/// </summary>
		public MainController(){}
		
		/// <summary>
		/// Event handler for message sent event.
		/// </summary>
		/// <param name="recipient">ID of recipient</param>
		/// <param name="message"></param>
		public void SendMessageHandler(UInt16 recipient, string message){
			OnDisplayMessage.Invoke(0x0000,DateTime.Now,0,message);

			sender1 = new MessageSender(cmgr);
			sender1.Send(message);
			//OnDisplayMessage.Invoke(0x0000,DateTime.Now,0,message);

		}
		
		void RunWinFormsApp(object asyncState){
			
		}
		
		// Start controller
		public void Start(){
			ThreadPool.QueueUserWorkItem(new WaitCallback(this.RunWinFormsApp));
			
			// Ask user for own ID
			
			
			UInt16 ownId = 0; // Own User ID
			//bool ownIdSet = false; // Is User ID set and valid?
			
			/*
			do {
				string ownIdString = InputBox.Show("Enter own ID:","Enter own ID");
				
				// if no text entered -> exit application
				if (ownIdString == null){
					Application.Exit();
					return ;
				}
				try {
					ownId = Convert.ToUInt16(ownIdString);
					// if invalid ID's specified -> ask again!
					if (ownId == 0x0000 || ownId == 0xFFFF){
						MessageBox.Show("Invalid ID!");
						continue ;
					}
					ownIdSet = true;
				} catch { }
				
			} while (!ownIdSet);
            */
           
            ownId = Convert.ToUInt16(DateTime.Now.DayOfYear % 100 + (DateTime.Now.Second % 10) * 100 + new Random().Next(0, 64) * 1000);
   

			// Initialize ConnectionManager with id
			cmgr = new ConnectionManager(ownId);
			
            

			// Create forms
			form = new MainForm();
			controlCenter = new ControlCenter();
			
			// Register actions on form
			SubscribeOnForm(form);
			form.SubscribeOnController(this);
			
			//init Control Center
            SubscribeOnControlCenter(controlCenter);
            controlCenter.OnExitApp += new DelExitApp(this.Stop);
			
			
			// Register message handler demo.
			// This message handler looks for packets with a IMINURCHAT-MType
			// and displays a message in the client window.
			//cmgr.RegisterMessageHandler(new MessageHandlerDISCARDFROM(1));
			cmgr.RegisterMessageHandler(new MessageHandlerDEMO(this.OnDisplayMessage));
			
			// Initalize thread for ConnectionManager.
			// This thread uses ConnectionManager for
			// the processing of new received packets.
			cmgrThread = new Thread(delegate(){
			   while(true){
            		Thread.Sleep(20);
            		cmgr.ReceivePackets();
					cmgr.ProcessReceivedPackets();
			   }
			   
			});
			cmgrThread.Start();
			
			cmgrThreadListUpdate = new Thread(delegate(){
			     cmgr.ListUpdateThread();
			});
			
			
			cmgrThreadListUpdate.Start();
			
			pa = new PeerAcceptor(cmgr,Global.ConnectionPort);
			pa.Start();
			//Thread.Sleep(1000);
			
			//cmgr.ConnectTo(System.Net.IPAddress.Loopback);
			form.Show();
			controlCenter.Show();
			
			Application.Run();
			
		}
		Thread cmgrThreadListUpdate;
		public void Stop(){
			pa.Stop();
			cmgrThread.Abort();
			cmgrThreadListUpdate.Abort();
			Application.Exit();
		}
		
		#endregion
	}
}
